package com.akk.exception;

import com.akk.utils.RestResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.client.RestClientResponseException;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import java.io.IOException;
import java.util.Date;

/**
 * ExceptionHandle
 */
@ControllerAdvice
public class ExceptionHandle extends ResponseEntityExceptionHandler {


    /**
     * 描述 : objectMapper
     */
    @Autowired
    private ObjectMapper objectMapper;

    /**
     * 异常处理
     *
     * @param ex      ex
     * @return ResponseEntity<Object>
     */
    @ExceptionHandler(value = Exception.class)
    public ResponseEntity<Object> exception(Exception ex, WebRequest request) {
        ex.printStackTrace();
        ResponseEntity<Object> objectResponseEntity = this.handleException(ex, request);
        return this.handleExceptionInternal(ex, null, objectResponseEntity.getHeaders(), objectResponseEntity.getStatusCode(), request);
    }

    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
        HttpStatus localHttpStatus = status;
        ErrorResult errorResult = buildError( ex);
        if(ex instanceof RestBusinessException){
            localHttpStatus = HttpStatus.BAD_REQUEST;
        }
        if(ex instanceof MissingServletRequestParameterException){
            errorResult.setMessage("缺失必要的参数.");
        }
        if(ex instanceof UnauthorizedException) {
            errorResult.setMessage("无访问该资源的权限.");
        }
        if (ex instanceof HttpRequestMethodNotSupportedException){
            errorResult.setMessage("请求方式错误.");
        }
        if (ex instanceof RestClientResponseException) { //rest请求异常
            try {
                RestClientResponseException restClientResponseException = (RestClientResponseException) ex;
                String data = restClientResponseException.getResponseBodyAsString();
                if (StringUtils.isNotBlank(data)) {
                    RestResponse<String> child = objectMapper.readValue(data, objectMapper.getTypeFactory().constructParametricType(RestResponse.class, String.class));
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return super.handleExceptionInternal(ex, new RestResponse<>(localHttpStatus, errorResult), headers, localHttpStatus, request);
    }

    /**
     * 描述 : 构造错误响应对象
     *
     * @param throwable         异常
     * @return 错误响应对象
     */
    public static ErrorResult buildError(Throwable throwable) {
        ErrorResult error = new ErrorResult();
        error.setType(throwable.getClass().getName());
        error.setMessage(throwable.getMessage());
        error.setDate(new Date());
        return error;
    }
}
